package com.dingding.util;

import java.util.Map;

import org.apache.log4j.Logger;
import org.junit.Test;

import com.dingding.common.core.config.JPushConfig;
import com.dingding.common.core.util.ToolUtil;

import cn.jpush.api.JPushClient;
import cn.jpush.api.common.resp.APIConnectionException;
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.AndroidNotification.Builder;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;

/**
 * 
 * @ClassName: JPushTest
 * @Description: 极光推送Demo
 * @author cheshaowei
 * @date 2015-8-18 下午07:43:22
 * 
 *       platform:推送平台设置 iOS Android audience:推送设备指定 notification:通知内容体
 *       是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存 message:消息内容体 是被推送到客户端的内容。与
 *       notification 一起二者必须有其一，可以二者并存 options:推送参数
 * 
 */
public class SendPushUtil {

	private static final Logger log = Logger.getLogger(SendPushUtil.class);

	private static JPushClient iosJPushClient = null;
	private static JPushClient androidJPushClient = null;

	static {
		iosJPushClient = new JPushClient(JPushConfig.getIOS_MASTER_SECRET(), JPushConfig.getIOS_APP_KEY());
		androidJPushClient = new JPushClient(JPushConfig.getANDROID_MASTER_SECRET(), JPushConfig.getANDROID_APP_KEY());
	}

	/**
	 * 
	 * @Title: sendPush
	 * @Description:推送消息
	 * @param aliasId
	 *            手机设备在极光绑定的设备别名
	 * @param alert
	 *            通知
	 * @param msgTitle
	 *            自定义标题
	 * @param msgContent
	 *            自定义消息的内容
	 * @param clientType
	 *            推送设备的类型(iOS/Android)
	 * @author cheshaowei
	 * 
	 */
	public static boolean sendPush(String aliasId, String alert, String msgTitle, String msgContent,
			String clientType) {

		// 创建推送客户端
		PushPayload pushPayload = null;
		// 推送结束后极光的返回对象
		PushResult pushResult = null;
		try {

			if ("Android".equals(clientType)) {

				// 推送内容包含通知、消息体
				if (ToolUtil.isNotBlank(alert) && ToolUtil.isNotBlank(msgTitle)) {
					pushPayload = sendAndroidNotificationMessageWithAliasId(aliasId, alert, msgContent);
					pushResult = androidJPushClient.sendPush(pushPayload);
				} else {// 推送内容不包含通知
					pushPayload = sendAndroidMessageWithAlias(aliasId, msgContent);
					pushResult = androidJPushClient.sendPush(pushPayload);
				}

			} else if ("iOS".equals(clientType)) {
				// 推送内容包含通知、消息体
				if (ToolUtil.isNotBlank(alert) && ToolUtil.isNotBlank(msgTitle)) {
					pushPayload = sendIosNotificationMessageWithAlias(aliasId, alert, msgContent);
					pushResult = iosJPushClient.sendPush(pushPayload);
				} else {// 推送内容不包含通知
					pushPayload = sendIosMessageWithAlias(aliasId, msgContent);
					pushResult = iosJPushClient.sendPush(pushPayload);
				}
			}

			return pushResult.isResultOK();

		} catch (APIRequestException e) {
			log.error("推送出现异常！");
			log.error("错误内容：" + e.getErrorMessage());
			log.error("推送消息ID:" + e.getMsgId());
			log.error(" 推送别名:" + aliasId + " 推送设备类型:" + clientType + " 推送内容:" + msgContent);
			return false;
		} catch (Exception e) {
			log.error("实时推送出现异常！类：SendPushUtil", e);
			return false;
		}
	}

	/**
	 * @Title: sendIosNotificationWithAlias @Description:封装iOS消息推送参数 @param
	 * aliasId 设备别名 @param alert 通知 @param msgContent 消息内容 @author
	 * cheshaowei @throws
	 */
	public static PushPayload sendIosNotificationMessageWithAlias(String aliasId, String alert, String msgContent) {

		PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.ios()) // 推送平台iOS
				// 设置iOS设备别名
				.setAudience(Audience.alias(aliasId))
				// 设置iOS通知及声音
				.setNotification(Notification.newBuilder()
						.addPlatformNotification(
								IosNotification.newBuilder().setAlert(alert).setSound("sounde.caf").build())
						.build())
				// 设置消息标题及内容
				.setMessage(Message.newBuilder().setMsgContent(msgContent).build())
				// 设置推送环境 true 生产环境 false 测试环境
				.setOptions(Options.newBuilder().setApnsProduction(JPushConfig.isENV_JPUSH()).build()).build();
		return payload;

	}

	/**
	 * 
	 * @Title: sendPush
	 * @Description:推送消息,自定义参数
	 * @param aliasId
	 *            手机设备在极光绑定的设备别名
	 * @param alert
	 *            通知
	 * @param msgTitle
	 *            自定义标题
	 * @param msgContent
	 *            自定义消息的内容
	 * @param clientType
	 *            推送设备的类型(iOS/Android)
	 * @param customParamName	自定义参数名称(iOS、Android需要)
	 * @param customParamValue	自定义值(iOS、Android需要)
	 * @param customParaName	自定义参数名称(仅Android需要,第二个字段暂定为Android所需的用户角色)
	 * @param customParaValue	自定义值(仅Android需要,第二个字段暂定为Android所需的用户角色)
	 * @author cheshaowei
	 * 
	 */
	public static boolean sendPushCustomParam(String aliasId, String alert, String msgTitle, String msgContent,
			String clientType, Map<String, String> map) {

		// 创建推送客户端
		PushPayload pushPayload = null;
		// 推送结束后极光的返回对象
		PushResult pushResult = null;
		try {

			if ("Android".equals(clientType)) {

				// 推送内容包含通知、消息体
				if (ToolUtil.isNotBlank(alert) && ToolUtil.isNotBlank(msgTitle)) {
					pushPayload = sendAndroidNotificationMessageWithAliasIdCustomParam(aliasId, alert, msgContent, map);
					pushResult = androidJPushClient.sendPush(pushPayload);
				} else {// 推送内容不包含通知
					pushPayload = sendAndroidMessageWithAlias(aliasId, msgContent);
					pushResult = androidJPushClient.sendPush(pushPayload);
				}

			} else if ("iOS".equals(clientType)) {
				// 推送内容包含通知、消息体
				if (ToolUtil.isNotBlank(alert) && ToolUtil.isNotBlank(msgTitle)) {
					pushPayload = sendIosNotificationMessageWithAliasCustomParam(aliasId, alert, msgContent, map);
					pushResult = iosJPushClient.sendPush(pushPayload);
				} else {// 推送内容不包含通知
					pushPayload = sendIosMessageWithAlias(aliasId, msgContent);
					pushResult = iosJPushClient.sendPush(pushPayload);
				}

			}

			return pushResult.isResultOK();

		} catch (APIRequestException e) {
			log.error("推送出现异常！");
			log.error("错误内容：" + e.getErrorMessage());
			log.error("推送消息ID:" + e.getMsgId());
			log.error(" 推送别名:" + aliasId + " 推送设备类型:" + clientType + " 推送内容:" + msgContent);
			return false;
		} catch (Exception e) {
			log.error("实时推送出现异常！类：SendPushUtil", e);
			return false;
		}
	}

	/**
	 * @Title:
	 * sendIosNotificationWithAlias @Description:封装iOS消息推送参数,自定义参数(oid) @param
	 * aliasId 设备别名 @param alert 通知 @param msgContent 消息内容 @author
	 * cheshaowei @throws
	 */
	public static PushPayload sendIosNotificationMessageWithAliasCustomParam(String aliasId, String alert,
			String msgContent, Map<String, String> map) {

		cn.jpush.api.push.model.notification.IosNotification.Builder builder = IosNotification.newBuilder();

		for (String key : map.keySet()) {
			builder.addExtra(key, map.get(key));
		}

		PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.ios()) // 推送平台iOS
				// 设置iOS设备别名
				.setAudience(Audience.alias(aliasId))
				// 设置iOS通知及声音
				.setNotification(Notification.newBuilder()
						.addPlatformNotification(builder.setAlert(alert).setSound("sounde.caf").build()).build())
				// 设置消息标题及内容
				.setMessage(Message.newBuilder().setMsgContent(msgContent).build())
				// 设置推送环境 true 生产环境 false 测试环境
				.setOptions(Options.newBuilder().setApnsProduction(JPushConfig.isENV_JPUSH()).build()).build();
		return payload;

	}

	/**
	 * 
	 * @Title:
	 * sendAndroidNotificationMessageWithAliasId @Description:封装Android消息推送参数(
	 * 自定义参数) @param aliasId Android设备别名 @param alert 通知 @param msgContent
	 * 消息内容 @author cheshaowei @throws
	 */
	public static PushPayload sendAndroidNotificationMessageWithAliasIdCustomParam(String aliasId, String alert,
			String msgContent, Map<String, String> map) throws APIConnectionException, APIRequestException {

		Builder builder = AndroidNotification.newBuilder();

		for (String key : map.keySet()) {
			builder.addExtra(key, map.get(key));
		}

		PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.android())
				.setAudience(Audience.alias(aliasId))
				.setNotification(
						Notification.newBuilder().addPlatformNotification(builder.setAlert(alert).build()).build())
				.setMessage(Message.newBuilder().setMsgContent(msgContent).build()).build();
		return payload;
	}

	/**
	 * @Title: sendIosNotificationWithAlias @Description:封装iOS消息推送参,无通知 @param
	 * aliasId 设备别名 @param msgContent 消息内容 @author cheshaowei @throws
	 */
	public static PushPayload sendIosMessageWithAlias(String aliasId, String msgContent) {
		PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.ios()).setAudience(Audience.alias(aliasId))
				.setMessage(Message.newBuilder().setMsgContent(msgContent).build())
				.setOptions(Options.newBuilder().setApnsProduction(JPushConfig.isENV_JPUSH()).build()).build();
		return payload;
	}

	/**
	 * @Title:
	 * sendAndroidMessageWithAlias @Description:封装Android消息推送参,无通知 @param
	 * aliasId 设备别名 @param msgContent 消息内容 @author cheshaowei @throws
	 */
	public static PushPayload sendAndroidMessageWithAlias(String aliasId, String msgContent)
			throws APIConnectionException, APIRequestException {
		PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.android())
				.setAudience(Audience.alias(aliasId)).setMessage(Message.newBuilder().setMsgContent(msgContent).build())
				.build();
		return payload;
	}

	/**
	 * 
	 * @Title:
	 * sendAndroidNotificationMessageWithAliasId @Description:封装Android消息推送参数 @param
	 * aliasId Android设备别名 @param alert 通知 @param msgContent 消息内容 @author
	 * cheshaowei @throws
	 */
	public static PushPayload sendAndroidNotificationMessageWithAliasId(String aliasId, String alert, String msgContent)
			throws APIConnectionException, APIRequestException {
		PushPayload payload = PushPayload.newBuilder().setPlatform(Platform.android())
				.setAudience(Audience.alias(aliasId)).setNotification(Notification.alert(alert))
				.setMessage(Message.newBuilder().setMsgContent(msgContent).build()).build();
		return payload;
	}

	/**
	 * 
	 * 
	 * @Title: sendTest @Description: @author cheshaowei @throws
	 */
	@Test
	public void sendTest() {
		sendPush("1448431734992187249", "通知", "标题", "我的极光测试", "iOS");
	}

}
